home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 17 / CU Amiga Magazine's Super CD-ROM 17 (1997)(EMAP Images)(GB)[!][issue 1997-12].iso / CUCD / Programming / DiceSource / master / Examples / CC / main.c < prev    next >
C/C++ Source or Header  |  1994-02-01  |  46KB  |  2,353 lines

  1.  
  2. /*
  3.  *  MAIN.C
  4.  *
  5.  *  (c)Copyright 1990, 1994 Obvious Implementations Corp.  All Rights Reserved
  6.  *
  7.  *  dcc <options> <files>
  8.  */
  9.  
  10. #include "defs.h"
  11. #ifdef COMMERCIAL
  12. #ifndef unix
  13. #include <lib/rexx.h>
  14. #endif
  15. #endif
  16.  
  17. #ifndef AZLAT_COMPAT
  18. #define DoLink_Dice    DoLink
  19. #define DoCompile_Dice    DoCompile
  20. #define DoAssemble_Dice DoAssemble
  21. #define DoPrelink_Dice    DoPrelink
  22. #endif
  23.  
  24. #include "DCC_rev.h"
  25.  
  26. static char *DCopyright =
  27. "Copyright (c) 1992,1993,1994 Obvious Implementations Corp., All Rights Reserved." VERSTAG;
  28.  
  29. Prototype   void    myexit(void);
  30. Prototype   int     main(int, char **);
  31. Prototype   void    AddFile(char *);
  32. Prototype   void    help(int);
  33. Prototype   char    *TmpFileName(char *);
  34. Prototype   char    *MungeFile(char *, char *, char *);
  35. Prototype   void    AddName(List *, char *, char *, short);
  36. Prototype   struct NameNode *AddOpt(List *, char *, char *);
  37. Prototype   char    *Tailer(char *);
  38. Prototype   char    *XFilePart(char *);
  39. Prototype   char    *OptListToStr(List *);
  40. Prototype   char    *OptListToStr2(List *, char *);
  41. Prototype   void    run_cmd(char *, char *);
  42. Prototype   int     OutOfDate(char *, char *);
  43. Prototype   void    HandleCFile(struct NameNode *, int);
  44. Prototype   void    HandleAFile(struct NameNode *, int);
  45. Prototype   void    PushTmpFile(char *);
  46. Prototype   void    PopTmpFile(char *);
  47. Prototype   long    LoadSegLock(long, char *);
  48. Prototype   void    DefaultOutName(void);
  49.  
  50. Prototype   int     DoCompile(char *, char *);
  51. Prototype   int     DoCompile_Dice(char *, char *);
  52. Prototype   int     DoCompile_Aztec(char *, char *);
  53. Prototype   int     DoCompile_Lattice(char *, char *);
  54. Prototype   int     DoAssemble(char *, char *, char *);
  55. Prototype   int     DoAssemble_Dice(char *, char *, char *);
  56. Prototype   int     DoAssemble_Aztec(char *, char *, char *);
  57. Prototype   int     DoAssemble_Lattice(char *, char *, char *);
  58. Prototype   char    *DoPrelink(void);
  59. Prototype   char    *DoPrelink_Dice(void);
  60. Prototype   char    *DoPrelink_Aztec(void);
  61. Prototype   char    *DoPrelink_Lattice(void);
  62. Prototype   int     DoLink(char *);
  63. Prototype   int     DoLink_Dice(char *);
  64. Prototype   int     DoLink_Aztec(char *);
  65. Prototype   int     DoLink_Lattice(char *);
  66. Prototype   char    *PathConvert(char *);
  67. Prototype   void    *GetHead(List *);
  68. Prototype   void    *GetSucc(Node *);
  69. Prototype   void    FlushStoredErrors(char *cfile);
  70. Prototype   int     HandleErrorRexx(char *, char *, int);
  71. Prototype   char    *ScanReplace(char *, char *, char *, char *);
  72. Prototype   char    *FullPathOf(char *);
  73. Prototype   char    *mergestr(const char *s1, const char *s2);
  74.  
  75. void OrderApp(char *);
  76. void AddLibApp(char *, char);
  77. void DelLibApp(char *, char);
  78. void uexit(int code);
  79.  
  80. /*
  81.  *  Note that we use exec_dcc if DCC, which only works with 'dcc' programs
  82.  *  thus, the executables are renamed to prevent problems.
  83.  */
  84.  
  85. Prototype __aligned char Buf[512];
  86. Prototype __aligned char CmdName[64];
  87.  
  88.  
  89. __aligned char Buf[512];
  90. __aligned char CmdName[64];
  91. char TmpFile[64];
  92. char ErrOptStr[128];
  93. char *ErrFile;
  94. char *OutFile;
  95. char *OutDir = NULL;
  96. #ifdef AMIGA
  97. char *TmpDir = "T:";
  98. #else
  99. char *TmpDir = "/tmp/";
  100. #endif
  101. char *DLib;
  102. char *AmigaLib;
  103. char *CLib;
  104. char ALibOS[4];
  105. char ALibApp[32] = { "s" };
  106. char CLibApp[32] = { "s" };
  107. char *RexxReplace[10];
  108. List TmpList;
  109. short dasAddSym;
  110. short ErrFileIsTmp;
  111. short NewOpt;
  112. short FastOpt;
  113. short FragOpt;
  114. short ChipOpt;
  115. short MC68020Opt;
  116. short MC68881Opt;
  117. short FFPOpt;
  118. short DDebug;
  119. short RegCallOpt;
  120. short NoHeirOpt;
  121. short NoEnvOpt;
  122. short NoCtlOpt;
  123. short SlashSlashOpt;
  124. short ProfOpt;
  125. short DLinkPostFixOpt;
  126. short UnixOpt;
  127. short UnixRCOpt;
  128. short ForkOpt;
  129. short UnixCommonOpt;
  130. short InlineCompOpt;
  131. short RexxOpt;
  132.  
  133. long    ExitCode;
  134.  
  135. char DLINK[32];
  136. char DAS[32];
  137. char DC1[32];
  138. char DCPP[32];
  139.  
  140. char *RexxHostName = "DCC";
  141.  
  142. char *SCode[4];
  143. char *IntOpt = "";
  144.  
  145.  
  146. typedef struct NameNode {
  147.     struct Node n_Node;
  148.     char    *n_In;
  149.     char    *n_Out;
  150.     short   n_IsType;
  151. } NameNode;
  152.  
  153. #define IS_CFILE    1
  154. #define IS_AFILE    2
  155. #define IS_OFILE    3
  156. #define IS_LIBFILE  4
  157. #define IS_TMP        0x100
  158. #define IsMask(istype) ((ubyte)istype)
  159.  
  160. List   FList;
  161. List   LList;
  162.  
  163. List   CppOptList;
  164. List   LinkOptList;
  165.  
  166. short    NoLink;
  167. short    NoAsm;
  168. short    SmallCode = 1;
  169. short    SmallData = 1;
  170. short    ConstCode;        /*    -ms            */
  171. short    AbsData;        /*    -mw, -ma        */
  172. short    ResOpt;
  173. short    AltSectOpt;
  174. short    SymOpt;
  175. short    RomOpt;
  176. short    ProtoOnlyOpt;
  177. short    NoIntermediateAssembly;
  178. short    PIOpt;
  179. short    GenStackOpt;
  180. short    GenLinkOpt;
  181. short    Verbose;
  182. short    NoDefaultLibs;
  183. short    CompilerOpt = DICE_C;
  184. long    AbsDataStart;        /*    -mw <addr>  */
  185. char    DebugOpts[64];
  186.  
  187. NameNode *InlineNode;
  188.  
  189. extern struct Library *SysBase;
  190.  
  191. void
  192. myexit()
  193. {
  194.     Node *node;
  195.  
  196.     while (node = RemHead(&TmpList)) {
  197.     remove(node->ln_Name);
  198.     free(node);
  199.     }
  200.     if (ErrFileIsTmp) {
  201.     fclose(stderr);
  202.     remove(ErrFile);
  203.     }
  204. }
  205.  
  206. int
  207. main(xac, xav)
  208. int xac;
  209. char *xav[];
  210. {
  211.     int fc = 0;
  212.     int ac;
  213.     char **av;
  214.  
  215.  
  216. #ifdef LATTICE
  217.     {
  218.     long n = (long)Buf;
  219.     if (n & 3) {
  220.         puts("software error, Buf not aligned");
  221.         uexit(25);
  222.     }
  223.     }
  224. #endif
  225. #ifdef NOTDEF
  226.     expand_args(xac, xav, &ac, &av);
  227. #else
  228.     ac = xac;
  229.     av = xav;
  230. #endif
  231.  
  232.     NewList(&FList);
  233.     NewList(&LList);
  234.  
  235.     NewList(&TmpList);
  236.  
  237.     NewList(&CppOptList);
  238.     NewList(&LinkOptList);
  239.  
  240.     atexit(myexit);
  241.  
  242.     if (ac == 1)
  243.     help(0);
  244.  
  245.     {
  246.     char *ptr = av[0];    /*  cmd name */
  247.     char prefix[32];
  248.     short i;
  249.  
  250.     for (i = strlen(ptr); i >= 0 && ptr[i] != ':' && ptr[i] != '/'; --i);
  251.     ++i;
  252.  
  253.     ptr = ptr + i;        /*  base name */
  254.     for (i = 0; ptr[i] && ptr[i] != '_'; ++i);
  255.     if (ptr[i] == '_') {
  256.         strncpy(prefix, ptr, i + 1);
  257.         prefix[i+1] = 0;
  258.     } else {
  259.         prefix[0] = 0;
  260.     }
  261.     sprintf(DLINK, "%s%s", prefix, "dlink");
  262.     sprintf(DAS  , "%s%s", prefix, "das");
  263.     sprintf(DC1  , "%s%s", prefix, "dc1");
  264.     sprintf(DCPP , "%s%s", prefix, "dcpp");
  265.     DLib = mergestr(DLIBPRE, prefix);
  266.     DLib = mergestr(DLib, DLIBPOS);
  267.     }
  268.     AmigaLib = mergestr(DLib, "amiga");
  269.     CLib = mergestr(DLib, "c");
  270.  
  271.     /*
  272.      *  2 x PIOpt + ResOpt
  273.      */
  274.  
  275.     SCode[0] = mergestr(DLib, "c.o");
  276.     SCode[1] = mergestr(DLib, "c.o");
  277.     SCode[2] = mergestr(DLib, "c_pi.o");
  278.     SCode[3] = mergestr(DLib, "c_pr.o");
  279.  
  280.     /*
  281.      *    check for -no-env option before processing DCCOPTS enviroment var
  282.      *    check for -no-ctl option before processing DCCOPTS file
  283.      */
  284.  
  285.     {
  286.     long i;
  287.  
  288.     for (i = 1; i < ac; ++i) {
  289.         if (strcmp(av[i], "-no-env") == 0) {
  290.         NoEnvOpt = 1;
  291.         break;
  292.         }
  293.         if (strcmp(av[i], "-no-ctl") == 0) {
  294.         NoCtlOpt = 1;
  295.         break;
  296.         }
  297.     }
  298.     }
  299.  
  300.     if (NoEnvOpt == 0) {
  301.     char **argv = av;
  302.     ac = ExtArgsEnv(ac, &argv, "DCCOPTS");
  303.     av = argv;
  304.     }
  305.     if (NoCtlOpt == 0) {
  306.     char **argv = av;
  307.     ac = ExtArgsFile(ac, &argv, "DCCOPTS");
  308.     av = argv;
  309.     }
  310.  
  311.     {
  312.     long i;
  313.     char *dummy;
  314.  
  315.     for (i = 1; i < ac; ++i) {
  316.         char *ptr = av[i];
  317.  
  318.         if (*ptr == '-') {
  319.         ptr += 2;
  320.  
  321.         switch(ptr[-1]) {
  322.         case '0':       /*  -020/-030/-040      */
  323.             MC68020Opt = 1;
  324.             break;
  325.         case '1':       /*  1.4, 1.3    */
  326.         case '2':       /*  2.0, 2.1..  */
  327.         case '3':
  328.         case '4':
  329.         case '5':
  330.             if (ptr[0] != '.')
  331.             help(1);
  332.             AddOpt(&CppOptList, ptr - 2, "");
  333.             ALibOS[0] = ptr[-1];
  334.             ALibOS[1] = ptr[1];
  335.             break;
  336.         case '8':
  337.             MC68881Opt = 1;
  338.             break;
  339.         case 'f':
  340.             if (*ptr == 0)
  341.             FastOpt = 1;
  342.             else if (*ptr == '0')
  343.             FastOpt = 0;
  344.             else if (*ptr == 'r') {
  345.             if (stricmp(ptr, "rag0") == 0)
  346.                 FragOpt = 0;
  347.             else
  348.                 FragOpt = 1;
  349.             } else if (*ptr == 'f')
  350.             FFPOpt = 1;
  351.             else if (*ptr == 'o') {
  352.             ForkOpt = 1;
  353.             AddLibApp(CLibApp, 'f');
  354.             }
  355.             break;
  356.         case 'i':   /*  -ieee   */
  357.             if (*ptr == 'e')
  358.             FFPOpt = 0;
  359.             else if (strncmp(ptr, "nt", 2) == 0) {
  360.             IntOpt = (ptr[2]) ? ptr + 2 : av[++i];
  361.             }
  362.             break;
  363.         case 'r':
  364.             if (strcmp(ptr, "om") == 0) {
  365.             RomOpt = 1;
  366.             } else if (*ptr == '0') {
  367.             ResOpt = 0;
  368.             } else {
  369.             if (PIOpt && ResOpt == 0)
  370.                 puts("DCC: Warning, -r -pi = -pr");
  371.             ResOpt = 1;
  372.             }
  373.             break;
  374.         case 'c':
  375.             if (*ptr == 0)
  376.             NoLink = 1;
  377.             else if (stricmp(ptr, "hip") == 0)
  378.             ChipOpt = 1;
  379.             else if (stricmp(ptr, "hip0") == 0)
  380.             ChipOpt = 0;
  381.             else
  382.             help(1);
  383.             break;
  384.         case 'a':
  385.             if (strcmp(ptr, "ztec") == 0) {
  386.             CompilerOpt = AZTEC_C;
  387.             break;
  388.             }
  389.             NoAsm = 1;
  390.             NoLink= 1;
  391.             break;
  392.         case 'g':
  393.             switch (*ptr) {
  394.             case 's':
  395.             GenStackOpt = 1;
  396.             if (ptr[1] == '0')
  397.                 GenStackOpt = 0;
  398.             break;
  399.             case 'l':
  400.             GenLinkOpt = 1;
  401.             break;
  402.             default:
  403.             help(1);
  404.             }
  405.             break;
  406.         case 'l':
  407.             if (strcmp(ptr, "attice") == 0) {
  408.             CompilerOpt = LATTICE_C;
  409.             break;
  410.             }
  411.             if (ptr[0] == '0' && ptr[1] == 0) {
  412.             NoDefaultLibs = 1;
  413.             break;
  414.             }
  415.             if (*ptr == 0)
  416.             ptr = av[++i];
  417.             AddName(&LList, ".lib", ptr, IS_LIBFILE);
  418.             DLinkPostFixOpt = 1;
  419.             break;
  420.         case 'L':   /*  -Ldir   */
  421.             if (ptr[0] == '0' && ptr[1] == 0) {
  422.             AddOpt(&LinkOptList, "-L0", "");
  423.             break;
  424.             }
  425.             if (*ptr == 0)
  426.             ptr = av[++i];
  427.             AddOpt(&LinkOptList, "-L", PathConvert(ptr));
  428.             break;
  429.         case 'I':   /*  -Idir   */
  430.             if (ptr[0] == '0' && ptr[1] == 0) {
  431.             AddOpt(&CppOptList, "-I0", "");
  432.             break;
  433.             }
  434.             if (*ptr == 0)
  435.             ptr = av[++i];
  436.             AddOpt(&CppOptList, "-I", PathConvert(ptr));
  437.             break;
  438.         case 'd':   /*  -dice -d<n> -d<debug_opts>  */
  439.             /*
  440.              *    note that -d<n> and -s<n> are mutually
  441.              *    exclusive in that -d1 implies -s and -s0
  442.              *    implies -d0
  443.              */
  444.  
  445.             if (strcmp(ptr, "ice") == 0) {
  446.             CompilerOpt = DICE_C;
  447.             break;
  448.             }
  449.             sprintf(DebugOpts, " -d%s", ptr);
  450.  
  451. #ifdef LATTICE
  452.             switch(atoi(ptr)) {
  453. #else
  454.             switch(strtol(ptr, NULL, 0)) {
  455. #endif
  456.             case 0:
  457.             SymOpt = 0;
  458.             break;
  459.             default:
  460.             SymOpt = 1;
  461.             }
  462.             break;
  463.         case 'Z':
  464.             if (atoi(ptr)) {
  465.             DDebug = atoi(ptr);
  466.             break;
  467.             }
  468.             break;
  469.         case 'D':   /*  -Ddefine[=str] */
  470.             if (*ptr == 0)
  471.             ptr = av[++i];
  472.             AddOpt(&CppOptList, "-D", ptr);
  473.             break;
  474.         case 'H':   /*  -H<path>=<include_name>    */
  475.             if (*ptr == 0)
  476.             ptr = av[++i];
  477.             AddOpt(&CppOptList, "-H", ptr);
  478.             break;
  479.         case 'u':
  480.             if (strcmp(ptr, "nixrc") == 0) {
  481.             UnixRCOpt = 1;
  482.             } else if (strcmp(ptr, "nix") == 0) {
  483.             UnixOpt = 1;
  484.             CLib = mergestr(DLib, "uc");
  485.             AddOpt(&CppOptList, "-unix", "");
  486.             }
  487.             break;
  488.         case 'U':   /*  -U      -undefine certain symbols */
  489.             AddOpt(&CppOptList, "-U", ptr);
  490.             break;
  491.         case 'o':
  492.             if (*ptr)
  493.             OutFile = PathConvert(ptr);
  494.             else
  495.             OutFile = PathConvert(av[++i]);
  496.             {
  497.             short idx = strlen(OutFile) - 2;
  498.             if (idx >= 0) {
  499.                 if (stricmp(OutFile + idx, ".h") == 0 || stricmp(OutFile + idx, ".c") == 0) {
  500.                 puts("ERROR! -o output file may not end in .c or .h!");
  501.                 uexit(20);
  502.                 }
  503.             }
  504.             }
  505.             break;
  506.         case 'O':
  507.             if (strcmp(ptr, "0") == 0)
  508.             OutDir = NULL;
  509.             else if (*ptr)
  510.             OutDir = PathConvert(ptr);
  511.             else
  512.             OutDir = PathConvert(av[++i]);
  513.             break;
  514.         case 'E':   /*  error output append */
  515.             {
  516.             char errtype = '1';
  517.             if (*ptr >= '1' && *ptr <= '9')
  518.             {
  519.                 errtype = *ptr;
  520.                 ptr++;
  521.             }
  522.             if (*ptr == 0)
  523.             ptr = av[++i];
  524.  
  525.             if (freopen(ptr, "a", stderr)) {
  526.                 if (ErrFile)
  527.                 remove(ErrFile);
  528.                 ErrFile = ptr;
  529.                 ErrFileIsTmp = 0;
  530.                 sprintf(ErrOptStr, " -E%c %s", errtype, ptr);
  531.             } else {
  532.                 printf("unable to append to %s\n", ptr);
  533.             }
  534.             }
  535.             break;
  536.         case 'p':
  537.             if (strcmp(ptr, "roto") == 0) {
  538.             ProtoOnlyOpt = 1;
  539.             } else if (strncmp(ptr, "rof", 3) == 0) {
  540.             if (ptr[3] != '0') {
  541.                 ProfOpt = atoi(ptr + 3);
  542.                 if (ProfOpt == 0)
  543.                 ProfOpt = 1;
  544.                 if (ProfOpt >= 2)
  545.                 AddLibApp(CLibApp, 'p');
  546.                 if (ProfOpt >= 3)
  547.                 AddLibApp(ALibApp, 'p');
  548.             } else {
  549.                 ProfOpt = 0;
  550.                 DelLibApp(ALibApp, 'p');
  551.                 DelLibApp(CLibApp, 'p');
  552.             }
  553.             } else if (strcmp(ptr, "i") == 0) {
  554.             PIOpt = 1;
  555.             if (ResOpt)
  556.                 puts("DCC: Warning, -r -pi = -pr");
  557.             } else if (strcmp(ptr, "r") == 0) {
  558.             PIOpt = 1;
  559.             ResOpt = 1;
  560.             } else {
  561.             help(1);
  562.             }
  563.             break;
  564.         case 'T':
  565.             if (*ptr)
  566.             TmpDir = PathConvert(ptr);
  567.             else
  568.             TmpDir = PathConvert(av[++i]);
  569.             break;
  570.         case 'm':
  571.             switch(*ptr) {
  572.             case 'C':
  573.             SmallCode = 0;
  574.             break;
  575.             case 'c':
  576.             SmallCode = 1;
  577.             break;
  578.             case 'D':
  579.             SmallData = 0;
  580.             DelLibApp(ALibApp, 's');
  581.             DelLibApp(CLibApp, 's');
  582.             AddLibApp(ALibApp, 'l');
  583.             AddLibApp(CLibApp, 'l');
  584.             break;
  585.             case 'd':
  586.             SmallData = 1;
  587.             DelLibApp(ALibApp, 'l');
  588.             DelLibApp(CLibApp, 'l');
  589.             AddLibApp(ALibApp, 's');
  590.             AddLibApp(CLibApp, 's');
  591.             break;
  592.             case 'a':
  593.             case 'w':
  594.             if (ptr[1] == 'a') {
  595.                 AbsData = 0;
  596.                 AbsDataStart = 0;
  597.             } else {
  598.                 AbsData = 1;
  599.  
  600.                 if (*ptr == 'a')
  601.                 AbsData = 2;
  602.  
  603.                 ++ptr;
  604.                 if (*ptr == 0)
  605.                 ptr = av[++i];
  606.  
  607. #ifdef LATTICE
  608.                 AbsDataStart = atoi(ptr);    /*  bug in lattice */
  609. #else
  610.                 AbsDataStart = strtol(ptr, &dummy, 0);
  611. #endif
  612.             }
  613.             break;
  614.             case 'r':
  615.             RegCallOpt = 1;
  616.             break;
  617.             case 'R':
  618.             AddLibApp(CLibApp, 'r');
  619.             AddLibApp(ALibApp, 'r');
  620.  
  621.             RegCallOpt = 2;
  622.             if (ptr[1] == 'R') {
  623.                 ProtoOnlyOpt = -1;    /*  force prototypes */
  624.                 RegCallOpt = 3;
  625.  
  626.                 switch(ptr[2]) {
  627.                 case 'X':
  628.                 RegCallOpt = 4;
  629.                 break;
  630.                 case 'Y':
  631.                 RegCallOpt = 5;
  632.                 break;
  633.                 case '0':
  634.                 RegCallOpt = 0;
  635.                 DelLibApp(CLibApp, 'r');
  636.                 DelLibApp(ALibApp, 'r');
  637.                 if (ProtoOnlyOpt == -1)
  638.                     ProtoOnlyOpt = 0;
  639.                 break;
  640.                 }
  641.             }
  642.             break;
  643.             case 's':
  644.             if (ptr[1])
  645.                 ConstCode = ptr[1] - '0';
  646.             else
  647.                 ConstCode = 1;
  648.             break;
  649.             case 'S':
  650.             /* XXX REMOVED */
  651.             /*ConstCode = 2;*/
  652.             break;
  653.             case 'u':
  654.             UnixCommonOpt = 1;
  655.             break;
  656.             case 'i':
  657.             if (ptr[1] == '0') {
  658.                 if (InlineCompOpt && InlineNode) {
  659.                 InlineCompOpt = 0;
  660.                 Remove(&InlineNode->n_Node);
  661.                 InlineNode = NULL;
  662.                 }
  663.             } else {
  664.                 if (InlineCompOpt == 0) {
  665.                 InlineCompOpt = 1;
  666.                 InlineNode = AddOpt(&CppOptList, "-D", "__DICE_INLINE");
  667.                 }
  668.             }
  669.             break;
  670.             default:
  671.             fprintf(stderr, "DCC: bad -m model\n");
  672.             uexit(20);
  673.             }
  674.             break;
  675.         case 'R':
  676. #ifdef COMMERCIAL
  677. #ifndef unix
  678.             /* substitution variables */
  679.  
  680.             if (*ptr >= '0' && *ptr <= '9')
  681.             RexxReplace[*ptr - '0'] = (ptr[1]) ? ptr + 1 : av[++i];
  682.  
  683.             /* rexx system up?    */
  684.  
  685.             if (RexxSysBase) {
  686.             RexxOpt = 1;
  687.             if (ErrFile == NULL) {
  688.                 char *ptr = TmpFileName(".e");
  689.  
  690.                 if (freopen(ptr, "a", stderr)) {
  691.                 ErrFile = ptr;
  692.                 ErrFileIsTmp = 1;
  693.                 sprintf(ErrOptStr," -EE %s", ptr);
  694.                 } else {
  695.                 printf("unable to append to %s\n", ptr);
  696.                 }
  697.             }
  698.             } else {
  699.             fprintf(stderr, "DCC: Warning: could open rexxsyslib.library!\n");
  700.             }
  701. #endif
  702. #endif
  703.             break;
  704.         case 's':
  705.             if (strcmp(ptr, "as") == 0) {
  706.             CompilerOpt = LATTICE_C;
  707.             } else if (strcmp(ptr, "ym") == 0) {
  708.                 dasAddSym = 1;
  709.             } else if (*ptr == '0') {
  710.             SymOpt = 0;
  711.             DebugOpts[0] = 0;
  712.             } else {
  713.             SymOpt = 1;
  714.             }
  715.             break;
  716.         case 'S':
  717.             if (*ptr == '0')
  718.             AltSectOpt = 0;
  719.             else
  720.             AltSectOpt = 1;
  721.             break;
  722.         case 'v':
  723.             if (*ptr == '0')
  724.             Verbose = 0;
  725.             else
  726.             Verbose = 1;
  727.             break;
  728.         case '/':
  729.             if (*ptr == '/') {
  730.             if (ptr[1] == '0')
  731.                 SlashSlashOpt = 0;
  732.             else
  733.                 SlashSlashOpt = 1;
  734.             break;
  735.             }
  736.             goto def;
  737.         case 'n':
  738.             if (strcmp(ptr, "ew") == 0) {
  739.             NewOpt = 1;
  740.             break;
  741.             }
  742.             if (strcmp(ptr, "ew0") == 0) {
  743.             NewOpt = 0;
  744.             break;
  745.             }
  746.             if (strcmp(ptr, "oheir") == 0) {
  747.             NoHeirOpt = 1;
  748.             break;
  749.             }
  750.             if (strcmp(ptr, "orom") == 0) {
  751.             RomOpt = 0;
  752.             break;
  753.             }
  754.             if (strcmp(ptr, "oproto") == 0) {
  755.             ProtoOnlyOpt = 0;
  756.             break;
  757.             }
  758.             if (strcmp(ptr, "o-env") == 0)
  759.             break;
  760.             if (strcmp(ptr, "o-ctl") == 0)
  761.             break;
  762.             /* fall through */
  763.         default:
  764.         def:
  765.             fprintf(stderr, "DCC: bad - option\n");
  766.             help(1);
  767.         }
  768.         continue;
  769.         }
  770.         if (*ptr == '+') {
  771.         ptr += 2;
  772.  
  773.         switch(ptr[-1]) {
  774.         case 'I':   /*  +Idir   */
  775.             if (*ptr == 0)
  776.             ptr = av[++i];
  777.             AddOpt(&CppOptList, "+I", ptr);
  778.             break;
  779.         default:
  780.             fprintf(stderr, "DCC: bad + option\n");
  781.             help(1);
  782.         }
  783.         continue;
  784.         }
  785.         if (*ptr == '@') {
  786.         FILE *fi = fopen(ptr + 1, "r");
  787.         char buf[128];
  788.  
  789.         if (fi == NULL) {
  790.             printf("unable to open %s\n", ptr + 1);
  791.             uexit(10);
  792.         }
  793.         while (fgets(buf, sizeof(buf), fi)) {
  794.             short len = strlen(buf);
  795.             if (len > 0)
  796.             buf[len-1] = 0;
  797.             if (buf[0] && buf[0] != ';' && buf[0] != '#') {
  798.             ++fc;
  799.             AddFile(buf);
  800.             }
  801.         }
  802.         fclose(fi);
  803.         continue;
  804.         }
  805.         ++fc;
  806.         AddFile(PathConvert(ptr));
  807.     }
  808.     if (i > ac) {
  809.         fprintf(stderr, "DCC: file argument missing\n");
  810.         help(1);
  811.     }
  812.     }
  813.  
  814. #ifdef AZLAT_COMPAT
  815.     if (CompilerOpt == AZTEC_C) {
  816.     puts("DCC in AZTEC mode");
  817.     FastOpt = 0;
  818.     NoIntermediateAssembly = 1;
  819.     }
  820.     if (CompilerOpt == LATTICE_C) {
  821.     puts("DCC in LATTICE mode");
  822.     FastOpt = 0;
  823.     NoIntermediateAssembly = 1;
  824.     }
  825. #else
  826.     if (CompilerOpt != DICE_C)
  827.     puts("DCC must be recompiled w/ AZLAT_COMPAT defined");
  828. #endif
  829.  
  830.     /*
  831.      *    Ensure CLibApp and ALibApp ordering and remove duplicates
  832.      */
  833.  
  834.     OrderApp(CLibApp);
  835.     OrderApp(ALibApp);
  836.  
  837.     /*
  838.      *    If this run is to generate an executable,
  839.      *
  840.      *    (a) determine the name of the executable and
  841.      *    (b) delete it before compiling anything
  842.      */
  843.  
  844.     if (NoLink == 0) {
  845.     DefaultOutName();    /*  default output name     */
  846.     remove(OutFile);    /*  make sure it's deleted  */
  847.     }
  848.  
  849.     /*
  850.      *    Compile sources into assembly
  851.      *    Assemble assembly into objects
  852.      *    Link objects into executable
  853.      */
  854.  
  855.     {
  856.     NameNode *nn;
  857.  
  858.     for (nn = GetHead(&FList); nn; nn = GetSucc(&nn->n_Node)) {
  859.         if (IsMask(nn->n_IsType) == IS_CFILE) {
  860.         HandleCFile(nn, fc);
  861.         }
  862.         if (NoAsm == 0 && IsMask(nn->n_IsType) == IS_AFILE) {
  863.         HandleAFile(nn, fc);
  864.         }
  865.     }
  866.     }
  867.  
  868.     /*
  869.      *    Link objects into executable
  870.      */
  871.  
  872.     if (NoLink == 0) {
  873.     char *lfile;
  874.  
  875.     lfile = DoPrelink();
  876.     if (lfile)
  877.         PushTmpFile(lfile);
  878.     DoLink(lfile);
  879.     if (lfile) {
  880.         PopTmpFile(lfile);
  881.         remove(lfile);
  882.         free(lfile);
  883.     }
  884.     }
  885.     uexit(ExitCode);
  886. }
  887.  
  888. void
  889. AddFile(ptr)
  890. char *ptr;
  891. {
  892.     char *t = Tailer(ptr);
  893.  
  894.     if (strncmp(t, "a", 1) == 0) {
  895.     AddName(&FList, NULL, ptr, IS_AFILE);
  896.     } else
  897.     if (strncmp(t, "o", 1) == 0) {
  898.     AddName(&FList, NULL, ptr, IS_OFILE);
  899.     } else
  900.     if (strncmp(t, "l", 1) == 0) {
  901.     AddName(&FList, NULL, ptr, IS_OFILE);
  902.     } else {
  903.     AddName(&FList, NULL, ptr, IS_CFILE);
  904.     }
  905. }
  906.  
  907. DoCompile_Dice(in, out)
  908. char *in;
  909. char *out;
  910. {
  911.     char *qq = "";
  912.     char *cptmp = TmpFileName(".i");
  913.     char *code = (SmallCode) ? " -mc" : " -mC";
  914.     char *data = (SmallData) ? " -md" : " -mD";
  915.     char *rc = qq;
  916.     char *absdata;
  917.     char *concode;
  918.     char *res  = (ResOpt) ? " -r" : qq;
  919.     char *verb = (Verbose) ? " -v" : qq;
  920.     char *optsect = (AltSectOpt) ? " -S" : qq;
  921.     char *protoonly = (ProtoOnlyOpt) ? " -proto" : qq;
  922.     char *prof = (ProfOpt) ? " -prof" : qq;
  923.     char *mc68020 = (MC68020Opt) ? " -020" : qq;
  924.     char *mc68881 = (MC68881Opt) ? " -881" : qq;
  925.     char *piopt;
  926.     char *ffp = (FFPOpt) ? " -ffp" : qq;
  927.     char *genstack = (GenStackOpt) ? " -gs" : qq;
  928.     char *genlink  = (GenLinkOpt) ? " -gl" : qq;
  929.     char *slashopt = (SlashSlashOpt) ? " -//" : qq;
  930.     char *forkopt = (ForkOpt) ? " -fork" : qq;
  931.     char *unixcomopt = (UnixCommonOpt) ? " -mu" : qq;
  932.     char *asmopt = (NoAsm) ? " -a" : qq;
  933.     char *intopt = (IntOpt[0]) ? " -int" : qq;
  934.  
  935.     switch(RegCallOpt) {
  936.     case 1:
  937.     rc = " -mr";
  938.     break;
  939.     case 2:
  940.     rc = " -mR";
  941.     break;
  942.     case 3:
  943.     rc = " -mRR";
  944.     break;
  945.     case 4:
  946.     rc = " -mRRX";
  947.     break;
  948.     case 5:
  949.     rc = " -mRRY";
  950.     break;
  951.     }
  952.  
  953.     switch(ConstCode) {
  954.     case 1:
  955.     concode = " -ms";
  956.     break;
  957.     case 2:
  958.     concode = " -mS";
  959.     break;
  960.     default:
  961.     concode = qq;
  962.     break;
  963.     }
  964.  
  965.     switch(AbsData) {
  966.     case 1:
  967.     absdata = " -mw";
  968.     break;
  969.     case 2:
  970.     absdata = " -ma";
  971.     break;
  972.     default:
  973.     absdata = qq;
  974.     break;
  975.     }
  976.  
  977.     if (PIOpt) {
  978.     if (ResOpt)
  979.         piopt = " -pr";
  980.     else
  981.         piopt = " -pi";
  982.     res = qq;
  983.     absdata = qq;
  984.     code = qq;
  985.     data = qq;
  986.     } else {
  987.     piopt = qq;
  988.     }
  989.  
  990.     PushTmpFile(cptmp);
  991.     sprintf(Buf, "%s %s -o %s%s%s%s%s",
  992.     DCPP, in, cptmp, ErrOptStr, OptListToStr(&CppOptList),
  993.     ffp, slashopt
  994.     );
  995.     run_cmd(in, Buf);
  996.     sprintf(Buf, "%s %s -o %s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s",
  997.     DC1, cptmp, out, code, data, rc, res, verb,
  998.     optsect, protoonly, prof, concode, absdata, piopt, ErrOptStr,
  999.     mc68020, mc68881, ffp, genstack, genlink, forkopt, unixcomopt,
  1000.     asmopt, intopt, IntOpt,
  1001.     DebugOpts
  1002.     );
  1003.     run_cmd(in, Buf);
  1004.     PopTmpFile(cptmp);
  1005.     remove(cptmp);
  1006.     free(cptmp);
  1007.     return(0);
  1008. }
  1009.  
  1010. DoAssemble_Dice(cpath, in, out)
  1011. char *cpath;
  1012. char *in;
  1013. char *out;
  1014. {
  1015.     short n;
  1016.  
  1017.     n = sprintf(Buf, "%s %s-o%s %s%s", DAS, (dasAddSym ? "-s ":""), out, in, ErrOptStr);
  1018.     if (cpath)
  1019.     sprintf(Buf+n, " -N%s", cpath);
  1020.     run_cmd(cpath, Buf);
  1021.     return(0);
  1022. }
  1023.  
  1024. char *
  1025. DoPrelink_Dice(void)
  1026. {
  1027.     NameNode *nn;
  1028.     char *ltmp = TmpFileName(".lnk");
  1029.     FILE *fi = fopen(ltmp, "w");
  1030.  
  1031.     if (fi == NULL) {
  1032.     fprintf(stderr, "DCC: couldn't create %s\n", ltmp);
  1033.     uexit(20);
  1034.     }
  1035.  
  1036.     for (nn = GetHead(&FList); nn; nn = GetSucc(&nn->n_Node)) {
  1037.     if (IsMask(nn->n_IsType) == IS_OFILE) {
  1038.         fputs(nn->n_In, fi);
  1039.         putc('\n', fi);
  1040.     }
  1041.     }
  1042.     while (nn = (NameNode *)RemHead(&LList)) {
  1043.     fputs(nn->n_In, fi);
  1044.     putc('\n', fi);
  1045.     }
  1046.  
  1047.     /*
  1048.      *    only small-data version of auto.lib is supported currently
  1049.      */
  1050.  
  1051.     if (RomOpt == 0 && NoDefaultLibs == 0) {
  1052.     fprintf(fi, "%s%s.lib", CLib, CLibApp);
  1053.     fprintf(fi, " %s%s%s.lib %sauto%s.lib\n",
  1054.         AmigaLib, ALibOS, ALibApp, DLib, (SmallData ? "s" : "l")
  1055.     );
  1056.     }
  1057.     fclose(fi);
  1058.     return(ltmp);
  1059. }
  1060.  
  1061. /*
  1062.  *  dlib:x.o is a special trailer for any autoinit code (in section autoinit,
  1063.  *  code)
  1064.  *
  1065.  *  This section is called in sequence just before main() with ac, av pushed on
  1066.  *  the stack.    The idea is that any module may reference an autoinit section to
  1067.  *  automatically initialize certain aspects of itself without requiring a call
  1068.  *  from the main program.
  1069.  */
  1070.  
  1071. DoLink_Dice(lfile)
  1072. char *lfile;
  1073. {
  1074.     char *qq = "";
  1075.     char *co = " ";
  1076.     char *ro = mergestr(DLib, "x.o");
  1077.     char *symopt = (SymOpt) ? " -s" : qq;
  1078.     char *resopt = (ResOpt) ? " -r" : qq;
  1079.     char *fragopt= (FragOpt) ? " -frag" : qq;
  1080.     char *chipopt= (ChipOpt) ? " -chip" : qq;
  1081.     char *postfix= qq;
  1082.     char *piopt;
  1083.     char absdata[20];
  1084.     char *verb = (Verbose) ? " -v" : qq;
  1085.  
  1086.     if (DLinkPostFixOpt) {
  1087.     static char PostFix[sizeof(CLibApp)+3];
  1088.     postfix = PostFix;
  1089.     sprintf(postfix, " -P%s", CLibApp);
  1090.     }
  1091.  
  1092.     if (RomOpt == 0 && NoDefaultLibs == 0) {
  1093.     co = SCode[(short)((PIOpt << 1) | ResOpt)];
  1094.     }
  1095.  
  1096.     if (AbsData) {
  1097.     sprintf(absdata, " -ma 0x%lx", AbsDataStart);
  1098.     } else {
  1099.     absdata[0] = 0;
  1100.     }
  1101.  
  1102.     if (PIOpt) {
  1103.     if (ResOpt)
  1104.         piopt = " -pr";
  1105.     else
  1106.         piopt = " -pi";
  1107.     resopt = qq;
  1108.     if (AbsData) {
  1109.         absdata[0] = 0;
  1110.         puts("Warning: cannot mix -pi and -ma/-mw");
  1111.     }
  1112.     } else {
  1113.     piopt = qq;
  1114.     }
  1115.     if (FragOpt) {
  1116.     if (ResOpt) {
  1117.         puts("Warning: cannot use -frag with -r");
  1118.         fragopt = qq;
  1119.     }
  1120.     }
  1121.  
  1122.     sprintf(Buf, "%s %s @%s %s -o %s%s%s%s%s%s%s%s%s%s%s%s",
  1123.     DLINK, co, lfile, ro, OutFile,
  1124.     symopt,
  1125.     resopt,
  1126.     fragopt,
  1127.     piopt,
  1128.     absdata,
  1129.     postfix,
  1130.     chipopt,
  1131.     OptListToStr(&LinkOptList),
  1132.     ErrOptStr,
  1133.     DebugOpts,
  1134.     verb
  1135.     );
  1136.     run_cmd("", Buf);
  1137.     free(ro);
  1138.  
  1139.     /*
  1140.      * Delete temporary objects
  1141.      */
  1142.  
  1143.     {
  1144.     NameNode *nn;
  1145.  
  1146.         for (nn = GetHead(&FList); nn; nn = GetSucc(&nn->n_Node)) {
  1147.         if (nn->n_IsType & IS_TMP)
  1148.         remove(nn->n_In);
  1149.     }
  1150.     }
  1151.     return(0);
  1152. }
  1153.  
  1154.  
  1155.  
  1156. void
  1157. help(code)
  1158. {
  1159. #ifdef _DCC
  1160.     printf("%s\n%s\n", VSTRING, DCopyright);
  1161. #endif
  1162.     uexit(code);
  1163. }
  1164.  
  1165. char *
  1166. TmpFileName(tail)
  1167. char *tail;
  1168. {
  1169.     char *buf = malloc(strlen(TmpDir) + strlen(tail) + 32);
  1170.     char dummy = 0;
  1171.  
  1172.     sprintf(buf, "%s%06lx%s", TmpDir, (long)&dummy >> 8, tail);
  1173.     return(buf);
  1174. }
  1175.  
  1176. /*
  1177.  *  file    -    file to modify
  1178.  *  hdr     -    new directory path to put file
  1179.  *  tail    -    new suffix
  1180.  *
  1181.  */
  1182.  
  1183. char *
  1184. MungeFile(file, hdr, tail)
  1185. char *file;
  1186. char *hdr;
  1187. char *tail;
  1188. {
  1189.     char *name = malloc(strlen(file) + (hdr ? strlen(hdr) : 0) + (tail ? strlen(tail) : 0) + 2);
  1190.     char *ptr;
  1191.     short n = 0;
  1192.  
  1193.     /*
  1194.      *    Prepend header, replacing the absolute portion of the file
  1195.      */
  1196.  
  1197.     if (hdr) {
  1198.     if (ptr = strchr(file, ':'))
  1199.         file = ptr + 1;
  1200.     n += sprintf(name + n, "%s", hdr);
  1201.  
  1202.     if (n && name[n-1] != ':' && name[n-1] != '/')
  1203.         name[n++] = '/';
  1204.     }
  1205.  
  1206.     /*
  1207.      *    The file
  1208.      */
  1209.  
  1210.     if (tail && (ptr = strrchr(file, '.'))) {
  1211.     n += sprintf(name + n, "%.*s", ptr - file, file);
  1212.     } else {
  1213.     n += sprintf(name + n, "%s", file);
  1214.     }
  1215.  
  1216.     /*
  1217.      *    Trailer
  1218.      */
  1219.  
  1220.     if (tail) {
  1221.     n += sprintf(name + n, "%s", tail);
  1222.     }
  1223.     name[n] = 0;
  1224.     return(name);
  1225. }
  1226.  
  1227. void
  1228. AddName(List *list, char *tailifnone, char *file, short isType)
  1229. {
  1230.     NameNode *nn = malloc(sizeof(NameNode));
  1231.     short i;
  1232.  
  1233.     for (i = strlen(file) - 1; i >= 0 && file[i] != '.'; --i) {
  1234.     if (file[i] == '/' || file[i] == ':')
  1235.         i = 0;
  1236.     }
  1237.  
  1238.     if (i < 0 && tailifnone) {
  1239.     nn->n_In = malloc(strlen(file) + strlen(tailifnone) + 1);
  1240.     sprintf(nn->n_In, "%s%s", file, tailifnone);
  1241.     } else {
  1242.     nn->n_In = malloc(strlen(file) + 1);
  1243.     strcpy(nn->n_In, file);
  1244.     }
  1245.     nn->n_Out = NULL;
  1246.     nn->n_IsType= isType;
  1247.     AddTail(list, &nn->n_Node);
  1248. }
  1249.  
  1250. NameNode *
  1251. AddOpt(list, opt, body)
  1252. List *list;
  1253. char *opt;
  1254. char *body;
  1255. {
  1256.     NameNode *nn = malloc(sizeof(NameNode));
  1257.  
  1258.     nn->n_In = opt;
  1259.     nn->n_Out= body;
  1260.     AddTail(list, &nn->n_Node);
  1261.     return(nn);
  1262. }
  1263.  
  1264. char *
  1265. Tailer(ptr)
  1266. char *ptr;
  1267. {
  1268.     short i;
  1269.  
  1270.     for (i = strlen(ptr) - 1; i >= 0 && ptr[i] != '.'; --i);
  1271.     if (i < 0)
  1272.     return("");
  1273.     return(ptr + i + 1);
  1274. }
  1275.  
  1276. char *
  1277. XFilePart(ptr)
  1278. char *ptr;
  1279. {
  1280.     short i;
  1281.  
  1282.     for (i = strlen(ptr) - 1; i >= 0 && ptr[i] != ':' && ptr[i] != '/'; --i);
  1283.     ++i;
  1284.     return(ptr + i);
  1285. }
  1286.  
  1287. char *
  1288. OptListToStr(list)
  1289. List *list;
  1290. {
  1291.     static char Tmp[512];
  1292.     short i;
  1293.     NameNode *scan;
  1294.  
  1295.     i = 0;
  1296.     Tmp[0] = 0;
  1297.     for (scan = (NameNode *)list->lh_Head; scan != (NameNode *)&list->lh_Tail; scan = (NameNode *)scan->n_Node.ln_Succ) {
  1298.     sprintf(Tmp + i, " %s%s", scan->n_In, scan->n_Out);
  1299.     i += strlen(Tmp + i);
  1300.     }
  1301.     return(Tmp);
  1302. }
  1303.  
  1304. #ifdef AZLAT_COMPAT
  1305.  
  1306. char *
  1307. OptListToStr2(list, cvt)
  1308. List *list;
  1309. char *cvt;
  1310. {
  1311.     static char Tmp[512];
  1312.     short i;
  1313.     NameNode *scan;
  1314.  
  1315.     i = 0;
  1316.     for (scan = (NameNode *)list->lh_Head; scan != (NameNode *)&list->lh_Tail; scan = (NameNode *)scan->n_Node.ln_Succ) {
  1317.     sprintf(Tmp + i, " %s%s", scan->n_In, scan->n_Out);
  1318.     {
  1319.         char *ptr;
  1320.         for (ptr = cvt; *ptr; ptr += 2) {
  1321.         if (Tmp[i+2] == ptr[0])
  1322.             Tmp[i+2] = ptr[1];
  1323.         }
  1324.     }
  1325.     i += strlen(Tmp + i);
  1326.     }
  1327.     return(Tmp);
  1328. }
  1329.  
  1330. #endif
  1331.  
  1332. /*
  1333.  *  run_cmd(buf)    buf[-1] is valid for BCPL stuff, buf[-1] is
  1334.  *            long word aligned.
  1335.  */
  1336.  
  1337. #ifdef AMIGA
  1338.  
  1339. void
  1340. run_cmd(cfile, buf)
  1341. char *cfile;        /* REXX support */
  1342. char *buf;
  1343. {
  1344.     short i;
  1345.     short j = strlen(buf);
  1346.     int r;
  1347.  
  1348.  
  1349.     if (ErrFile)
  1350.     fclose(stderr);
  1351.  
  1352.     /*
  1353.      *    top (hack to support REXX fix/continue)
  1354.      */
  1355.  
  1356. top:
  1357.     if (Verbose)
  1358.     printf("%s\n", buf);
  1359.  
  1360.  
  1361. #if INCLUDE_VERSION >= 36
  1362.     if (SysBase->lib_Version >= 36) {
  1363.     long seg;
  1364.     long lock = NULL;
  1365.  
  1366.     Process *proc = (Process *)FindTask(NULL);
  1367.     CLI *cli = BTOC(proc->pr_CLI, CLI);
  1368.     long oldCommandName;
  1369.  
  1370.     dbprintf(("cmd-begin\n"));
  1371.  
  1372.     for (i = 0; buf[i] && buf[i] != ' '; ++i)
  1373.         ;
  1374.     movmem(buf, CmdName + 1, i);
  1375.     CmdName[0] = i;
  1376.     CmdName[i+1] = 0;
  1377.  
  1378.     if (cli) {
  1379.         oldCommandName = (long)cli->cli_CommandName;
  1380.         cli->cli_CommandName = CTOB(CmdName);
  1381.     }
  1382.  
  1383.     if (seg = (long)FindSegment(CmdName + 1, 0L, 0)) {
  1384.         r = RunCommand(((long *)seg)[2], 16384, buf + i + 1, strlen(buf + i + 1));
  1385.     } else if ((lock = _SearchPath(CmdName + 1)) && (seg = LoadSegLock(lock, ""))) {
  1386.         r = RunCommand(seg, 16384, buf + i + 1, strlen(buf + i + 1));
  1387.         UnLoadSeg(seg);
  1388.     } else if ((lock = Lock("dcc:bin", SHARED_LOCK)) && (seg = LoadSegLock(lock, CmdName + 1))) {
  1389.         r = RunCommand(seg, 16384, buf + i + 1, strlen(buf + i + 1));
  1390.         UnLoadSeg(seg);
  1391.     } else {
  1392.         printf("Unable to find executable %s resident, via your path\n", CmdName + 1);
  1393.         printf("or in DCC:BIN!\n");
  1394.         r = 20;
  1395.     }
  1396.     if (lock)
  1397.         UnLock(lock);
  1398.     if (cli)
  1399.         cli->cli_CommandName = (BSTR)oldCommandName;
  1400.  
  1401.     dbprintf(("cmd-end\n"));
  1402.     } else {
  1403. #else
  1404.     {
  1405. #endif
  1406.  
  1407. #ifdef _DCC
  1408.     if (FastOpt == 0) {
  1409. #endif
  1410.         if (Execute(buf, NULL, Output()) != -1) {
  1411.         printf("Unable to Execute %s\n", buf);
  1412.         uexit(20);
  1413.         }
  1414.         r = 0;
  1415.  
  1416. #ifdef _DCC
  1417.     } else {
  1418.         for (i = 0; buf[i] && buf[i] != ' '; ++i)
  1419.         ;
  1420.         buf[i] = 0;
  1421.         if (i != j) {
  1422.         for (++i; buf[i] == ' '; ++i)
  1423.             ;
  1424.         }
  1425.         r = exec_dcc(buf, buf + i);
  1426.     }
  1427. #endif
  1428.     }
  1429.     if (r)
  1430.     printf("Exit code %d\n", r);
  1431. #ifdef COMMERCIAL
  1432. #ifndef unix
  1433.     if (RexxOpt)
  1434.     {
  1435.     if (r)
  1436.     {
  1437.         long rr = HandleErrorRexx(cfile, buf, r);
  1438.         if (rr == 2)
  1439.         goto top;
  1440.     } else {
  1441.         FlushStoredErrors(cfile);
  1442.     }
  1443.     }
  1444. #endif
  1445. #endif
  1446.     if (ExitCode < r)
  1447.     ExitCode = r;
  1448.     if (ExitCode > 5)
  1449.     uexit(ExitCode);
  1450.  
  1451.     /*
  1452.      *    close and reopen file to 'sync' it
  1453.      */
  1454.  
  1455.     if (r && ErrFile)
  1456.     freopen(ErrFile, "a", stderr);
  1457. }
  1458.  
  1459. #else
  1460.  
  1461. #include <sys/wait.h>
  1462.  
  1463. void
  1464. run_cmd(cfile, buf)
  1465. char *cfile;        /* REXX support */
  1466. char *buf;
  1467. {
  1468.     int r;
  1469.  
  1470.     if (Verbose)
  1471.     printf("%s\n", buf);
  1472.  
  1473.     if ((r = vfork()) == 0) {
  1474.     execlp("/bin/sh", "/bin/sh", "-c", buf, 0);
  1475.     uexit(30);
  1476.     } else {
  1477.     union wait uwait;
  1478.     while (wait(&uwait) != r || WIFEXITED(uwait) == 0)
  1479.         ;
  1480.     r = uwait.w_retcode;
  1481.     }
  1482.  
  1483.     if (r)
  1484.     printf("Exit code %d\n", r);
  1485.     if (ExitCode < r)
  1486.     ExitCode = r;
  1487.     if (ExitCode > 5)
  1488.     uexit(ExitCode);
  1489. }
  1490.  
  1491. #endif
  1492.  
  1493. #ifdef AMIGA
  1494.  
  1495. int
  1496. OutOfDate(in, out)
  1497. char *in;
  1498. char *out;
  1499. {
  1500.     static FIB *InFib;
  1501.     static FIB *OutFib;
  1502.     BPTR inLock, outLock;
  1503.     FIB *inFib;
  1504.     FIB *outFib;
  1505.     int r = 1;
  1506.  
  1507.     if (NewOpt == 0)
  1508.     return(1);
  1509.  
  1510.     if (InFib == NULL) {
  1511.     InFib = malloc(sizeof(FIB));
  1512.     OutFib = malloc(sizeof(FIB));
  1513.     }
  1514.     inFib = InFib;
  1515.     outFib = OutFib;
  1516.  
  1517.     if (inLock = Lock(in, SHARED_LOCK)) {
  1518.     if (outLock = Lock(out, SHARED_LOCK)) {
  1519.         if (Examine(inLock, inFib) && Examine(outLock, outFib)) {
  1520.         if (inFib->fib_Date.ds_Days < outFib->fib_Date.ds_Days)
  1521.             r = 0;
  1522.         else if (inFib->fib_Date.ds_Days == outFib->fib_Date.ds_Days) {
  1523.             if (inFib->fib_Date.ds_Minute < outFib->fib_Date.ds_Minute)
  1524.             r = 0;
  1525.             else if (inFib->fib_Date.ds_Minute == outFib->fib_Date.ds_Minute) {
  1526.             if (inFib->fib_Date.ds_Tick < outFib->fib_Date.ds_Tick)
  1527.                 r = 0;
  1528.             }
  1529.         }
  1530.         }
  1531.         UnLock(outLock);
  1532.     }
  1533.     UnLock(inLock);
  1534.     }
  1535.     return(r);
  1536. }
  1537.  
  1538. #else
  1539.  
  1540. int
  1541. OutOfDate(in, out)
  1542. char *in;
  1543. char *out;
  1544. {
  1545.     struct stat instat;
  1546.     struct stat outstat;
  1547.     int r = 1;
  1548.  
  1549.     if (NewOpt == 0)
  1550.     return(1);
  1551.  
  1552.     if (stat(in, &instat) == 0) {
  1553.     if (stat(out, &outstat) == 0) {
  1554.         if (instat.st_mtime < outstat.st_mtime)
  1555.         r = 0;
  1556.     }
  1557.     }
  1558.     return(r);
  1559. }
  1560.  
  1561. #endif
  1562.  
  1563. void
  1564. HandleCFile(nn, fc)
  1565. NameNode *nn;
  1566. int fc;
  1567. {
  1568.     char *asmName;
  1569.     char *objName;
  1570.  
  1571.     if (fc == 1 && OutFile && NoAsm)
  1572.     asmName = OutFile;
  1573.     else if (NoAsm)
  1574.     asmName = MungeFile(nn->n_In, OutDir, ".a");
  1575.     else
  1576.     asmName = MungeFile(XFilePart(nn->n_In), TmpDir, ".a");
  1577.  
  1578.     nn->n_IsType = IS_OFILE;
  1579.  
  1580.     if (fc == 1 && OutFile && NoLink) {
  1581.     objName = OutFile;
  1582.     } else if (NoLink) {
  1583.     objName = MungeFile(nn->n_In, OutDir, ".o");
  1584.     } else {
  1585.     objName = MungeFile(XFilePart(nn->n_In), TmpDir, ".o");
  1586.     nn->n_IsType |= IS_TMP;
  1587.     }
  1588.  
  1589.     if (NoAsm) {    /*  in -> asmName        */
  1590.     if (OutOfDate(nn->n_In, asmName))
  1591.         DoCompile(nn->n_In, asmName);
  1592.     } else {        /*  in -> asmName -> objName*/
  1593.     if (OutOfDate(nn->n_In, objName)) {
  1594.         PushTmpFile(asmName);
  1595.         if (NoIntermediateAssembly) {
  1596.         DoCompile(nn->n_In, objName);
  1597.         } else {
  1598.         DoCompile(nn->n_In, asmName);
  1599.         if (NoHeirOpt == 0)
  1600.             CreateObjPath(objName);
  1601.         DoAssemble(nn->n_In, asmName, objName);
  1602.         }
  1603.         PopTmpFile(asmName);
  1604.         remove(asmName);
  1605.     }
  1606.     }
  1607.     nn->n_In = strdup(objName);
  1608. }
  1609.  
  1610. void
  1611. HandleAFile(nn, fc)
  1612. NameNode *nn;
  1613. int fc;
  1614. {
  1615.     char *objName;
  1616.  
  1617.     nn->n_IsType = IS_OFILE;
  1618.  
  1619.     if (fc == 1 && OutFile && NoLink) {
  1620.     objName = OutFile;
  1621.     } else if (NoLink) {
  1622.     objName = MungeFile(nn->n_In, OutDir, ".o");
  1623.     } else {
  1624.     objName = MungeFile(XFilePart(nn->n_In), TmpDir, ".o");
  1625.     nn->n_IsType |= IS_TMP;
  1626.     }
  1627.  
  1628.     if (OutOfDate(nn->n_In, objName)) {
  1629.     if (NoHeirOpt == 0)
  1630.         CreateObjPath(objName);
  1631.     DoAssemble(NULL, nn->n_In, objName);
  1632.     }
  1633.     nn->n_In = strdup(objName);
  1634. }
  1635.  
  1636. void
  1637. PushTmpFile(name)
  1638. char *name;
  1639. {
  1640.     Node *node = malloc(sizeof(Node) + strlen(name) + 1);
  1641.     if (node == NULL) {
  1642.     puts("Ran out of memory!");
  1643.     uexit(25);
  1644.     }
  1645.     node->ln_Name = (char *)(node + 1);
  1646.     strcpy(node->ln_Name, name);
  1647.     AddHead(&TmpList, node);
  1648. }
  1649.  
  1650. void
  1651. PopTmpFile(name)
  1652. char *name;
  1653. {
  1654.     Node *node = RemHead(&TmpList);
  1655.  
  1656.     if (node == NULL || strcmp(name, node->ln_Name) != 0) {
  1657.     puts("PopTmpFile: software error");
  1658.     uexit(20);
  1659.     }
  1660.     free(node);
  1661. }
  1662.  
  1663. #ifdef AMIGA
  1664.  
  1665. long
  1666. LoadSegLock(lock, cmd)
  1667. long lock;
  1668. char *cmd;
  1669. {
  1670.     long oldLock;
  1671.     long seg;
  1672.  
  1673.     oldLock = CurrentDir(lock);
  1674.     seg = LoadSeg(cmd);
  1675.     CurrentDir(oldLock);
  1676.     return(seg);
  1677. }
  1678.  
  1679. #endif
  1680.  
  1681. void
  1682. DefaultOutName(void)
  1683. {
  1684.     NameNode *nn;
  1685.  
  1686.     /*
  1687.      *    if no output file name set and only one source file was specified,
  1688.      *    set output file name based on said file
  1689.      */
  1690.  
  1691.     if (OutFile == NULL) {
  1692.     OutFile = "a.out";
  1693.  
  1694.     if (nn = GetHead(&FList)) {
  1695.         /*if (GetSucc(&nn->n_Node) == NULL)*/ {
  1696.         char *ptr = strdup(nn->n_In);
  1697.         char *p0;
  1698.  
  1699.         if (p0 = strrchr(ptr, '.')) {
  1700.             *p0 = 0;
  1701.             OutFile = ptr;
  1702.         }
  1703.         }
  1704.     }
  1705.     }
  1706. }
  1707.  
  1708. /*
  1709.  *    AZTEC C, LATTICE C COMPATIBILITY OPTIONS
  1710.  */
  1711.  
  1712. #ifdef AZLAT_COMPAT
  1713.  
  1714. DoLink(lfile)
  1715. char *lfile;
  1716. {
  1717.     switch(CompilerOpt) {
  1718.     case DICE_C:
  1719.     return(DoLink_Dice(lfile));
  1720.     case LATTICE_C:
  1721.     return(DoLink_Lattice(lfile));
  1722.     case AZTEC_C:
  1723.     return(DoLink_Aztec(lfile));
  1724.     }
  1725. }
  1726.  
  1727. DoCompile(in, out)
  1728. char *in;
  1729. char *out;
  1730. {
  1731.     switch(CompilerOpt) {
  1732.     case DICE_C:
  1733.     return(DoCompile_Dice(in, out));
  1734.     case LATTICE_C:
  1735.     return(DoCompile_Lattice(in, out));
  1736.     case AZTEC_C:
  1737.     return(DoCompile_Aztec(in, out));
  1738.     }
  1739.     return(0);
  1740. }
  1741.  
  1742. DoAssemble(cfile, in, out)
  1743. char *cfile;
  1744. char *in;
  1745. char *out;
  1746. {
  1747.     switch(CompilerOpt) {
  1748.     case DICE_C:
  1749.     return(DoAssemble_Dice(cfile, in, out));
  1750.     case LATTICE_C:
  1751.     return(DoAssemble_Lattice(cfile, in, out));
  1752.     case AZTEC_C:
  1753.     return(DoAssemble_Aztec(cfile, in, out));
  1754.     }
  1755.     return(0);
  1756. }
  1757.  
  1758. char *
  1759. DoPrelink(void)
  1760. {
  1761.     switch(CompilerOpt) {
  1762.     case DICE_C:
  1763.     return(DoPrelink_Dice());
  1764.     case LATTICE_C:
  1765.     return(DoPrelink_Lattice());
  1766.     case AZTEC_C:
  1767.     return(DoPrelink_Aztec());
  1768.     }
  1769.     return(0);
  1770. }
  1771.  
  1772. /*
  1773.  *    ------------------------------------------------------------------
  1774.  */
  1775.  
  1776. DoCompile_Lattice(in, out)
  1777. char *in;
  1778. char *out;
  1779. {
  1780.     char *qq = "";
  1781.     char *cptmp = TmpFileName(".i");
  1782.     char *data = (SmallData) ? qq : " -b0";
  1783.  
  1784.     sprintf(Buf, "lc -o%s %s %s %s",
  1785.     out, OptListToStr2(&CppOptList, "DdIi"), data, in
  1786.     );
  1787.     run_cmd(in, Buf);
  1788.  
  1789.     free(cptmp);
  1790.     return(0);
  1791. }
  1792.  
  1793. DoAssemble_Lattice(cfile, in, out)
  1794. char *cfile;
  1795. char *in;
  1796. char *out;
  1797. {
  1798.     sprintf(Buf, "asm -o%s %s", out, in);
  1799.     run_cmd(cfile, Buf);
  1800.     return(0);
  1801. }
  1802.  
  1803. char *
  1804. DoPrelink_Lattice(void)
  1805. {
  1806.     NameNode *nn;
  1807.     char *ltmp = TmpFileName(".lnk");
  1808.     FILE *fi = fopen(ltmp, "w");
  1809.     short libs = 0;
  1810.  
  1811.     if (fi == NULL) {
  1812.     fprintf(stderr, "DCC: couldn't create %s\n", ltmp);
  1813.     uexit(20);
  1814.     }
  1815.  
  1816.     for (nn = GetHead(&FList); nn; nn = GetSucc(&nn->n_Node)) {
  1817.     if (IsMask(nn->n_IsType) == IS_OFILE) {
  1818.         fputs(nn->n_In, fi);
  1819.         putc('\n', fi);
  1820.     }
  1821.     }
  1822.  
  1823.     while (nn = (NameNode *)RemHead(&LList)) {
  1824.     if (libs == 0) {
  1825.         fprintf(fi, "LIB ");
  1826.         libs = 1;
  1827.     }
  1828.     fputs(nn->n_In, fi);
  1829.     putc('\n', fi);
  1830.     }
  1831.     if (RomOpt == 0 && NoDefaultLibs == 0) {
  1832.     if (libs == 0) {
  1833.         fprintf(fi, "LIB ");
  1834.         libs = 1;
  1835.     }
  1836.     fprintf(fi, "lib:lc.lib lib:amiga.lib\n");
  1837.     }
  1838.  
  1839.     fclose(fi);
  1840.     return(ltmp);
  1841. }
  1842.  
  1843. DoLink_Lattice(lfile)
  1844. char *lfile;
  1845. {
  1846.     char *qq = "";
  1847.     char *co = " ";
  1848.     char *symopt = (SymOpt) ? " ADDSYM" : qq;
  1849.     char *scopt = (SmallData) ? " SD" : qq;
  1850.     char *sdopt = (SmallCode) ? " SC" : qq;
  1851.  
  1852.     if (RomOpt == 0 && NoDefaultLibs == 0) {       /*  RomOpt PIOpt ResOpt */
  1853.     static char *SCode[] = { "lib:c.o",         /*    0      0      0   */
  1854.                  "lib:cres.o",      /*    0      0      1   */
  1855.                  "lib:c.o",         /*    0      1      0   */
  1856.                  "lib:cres.o"       /*    0      1      1   */
  1857.                    };
  1858.     co = SCode[(short)((PIOpt << 1) | ResOpt)];
  1859.     }
  1860.  
  1861.     sprintf(Buf, "BLink from %s with %s to %s%s%s%s",
  1862.     co, lfile, OutFile, symopt, scopt, sdopt
  1863.     );
  1864.     run_cmd("", Buf);
  1865.     return(0);
  1866. }
  1867.  
  1868. /*
  1869.  *  ---------------------------------------------------------------------
  1870.  */
  1871.  
  1872. DoCompile_Aztec(in, out)
  1873. char *in;
  1874. char *out;
  1875. {
  1876.     char *qq = "";
  1877.     char *cptmp = TmpFileName(".i");
  1878.     char *data = (SmallData) ? qq : qq;
  1879.  
  1880.     sprintf(Buf, "cc %s %s %s -o %s",
  1881.     OptListToStr2(&CppOptList, ""), data, in, out
  1882.     );
  1883.     run_cmd(in, Buf);
  1884.  
  1885.     free(cptmp);
  1886.     return(0);
  1887. }
  1888.  
  1889. DoAssemble_Aztec(cfile, in, out)
  1890. char *cfile;
  1891. char *in;
  1892. char *out;
  1893. {
  1894.     sprintf(Buf, "as %s -o %s", in, out);
  1895.     run_cmd(cfile, Buf);
  1896.     return(0);
  1897. }
  1898.  
  1899. char *
  1900. DoPrelink_Aztec(void)
  1901. {
  1902.     NameNode *nn;
  1903.     char *ltmp = TmpFileName(".lnk");
  1904.     FILE *fi = fopen(ltmp, "w");
  1905.  
  1906.     if (fi == NULL) {
  1907.     fprintf(stderr, "DCC: couldn't create %s\n", ltmp);
  1908.     uexit(20);
  1909.     }
  1910.  
  1911.     for (nn = GetHead(&FList); nn; nn = GetSucc(&nn->n_Node)) {
  1912.     if (IsMask(nn->n_IsType) == IS_OFILE) {
  1913.         fputs(nn->n_In, fi);
  1914.         putc('\n', fi);
  1915.     }
  1916.     }
  1917.     while (nn = (NameNode *)RemHead(&LList)) {
  1918.     fputs(nn->n_In, fi);
  1919.     putc('\n', fi);
  1920.     }
  1921.     if (RomOpt == 0 && NoDefaultLibs == 0) {
  1922.     fprintf(fi, "-lc\n");
  1923.     }
  1924.     fclose(fi);
  1925.     return(ltmp);
  1926. }
  1927.  
  1928. DoLink_Aztec(lfile)
  1929. char *lfile;
  1930. {
  1931.     char *qq = "";
  1932.  
  1933.     sprintf(Buf, "ln -f %s -o %s", lfile, OutFile);
  1934.     run_cmd("", Buf);
  1935.     return(0);
  1936. }
  1937.  
  1938. #endif
  1939.  
  1940. void
  1941. OrderApp(buf)
  1942. char *buf;
  1943. {
  1944.     short i;
  1945.     short c;
  1946.     char sort[26];
  1947.  
  1948.     setmem(sort, sizeof(sort), 0);
  1949.     for (i = 0; c = buf[i]; ++i) {
  1950.     if (c >= 'a' && c <= 'z')
  1951.         sort[c-'a'] = 1;
  1952.     }
  1953.     for (i = sizeof(sort) - 1, c = 0; i >= 0; --i) {
  1954.     if (sort[i])
  1955.         buf[c++] = i + 'a';
  1956.     }
  1957.     buf[c] = 0;
  1958. }
  1959.  
  1960. void
  1961. AddLibApp(char *buf, char c)
  1962. {
  1963.     short i = strlen(buf);
  1964.  
  1965.     if (strchr(buf, c) == NULL) {
  1966.     buf[i+0] = c;
  1967.     buf[i+1] = 0;
  1968.     }
  1969. }
  1970.  
  1971. void
  1972. DelLibApp(char *buf, char c)
  1973. {
  1974.     char *ptr;
  1975.  
  1976.     if (ptr = strchr(buf, c))
  1977.     movmem(ptr + 1, ptr, strlen(ptr + 1) + 1);
  1978. }
  1979.  
  1980. char *
  1981. PathConvert(path)
  1982. char *path;
  1983. {
  1984. #ifdef _DCC
  1985.     if (strstr(path, "./") || strstr(path, "../"))
  1986.     return(strdup(UnixToAmigaPath(path)));
  1987. #endif
  1988.     return(path);
  1989. }
  1990.  
  1991. void *
  1992. GetHead(list)
  1993. List *list;
  1994. {
  1995.     if (list->lh_Head != (Node *)&list->lh_Tail)
  1996.     return(list->lh_Head);
  1997.     return(NULL);
  1998. }
  1999.  
  2000. void *
  2001. GetSucc(node)
  2002. Node *node;
  2003. {
  2004.     Node *r = node->ln_Succ;
  2005.  
  2006.     if (r->ln_Succ)
  2007.     return(r);
  2008.     return(NULL);
  2009. }
  2010.  
  2011. char *
  2012. mergestr(const char *s1, const char *s2)
  2013. {
  2014.     char *ptr = malloc(strlen(s1) + strlen(s2) + 1);
  2015.     sprintf(ptr, "%s%s", s1, s2);
  2016.     return(ptr);
  2017. }
  2018.  
  2019.  
  2020. #ifdef COMMERCIAL
  2021. #ifndef unix
  2022.  
  2023. void
  2024. FlushStoredErrors(cfile)
  2025. char *cfile;
  2026. {
  2027.     char *fullPath;
  2028.     char *port = "DICE_ERROR_PARSER";
  2029.  
  2030.     if ( (cfile != NULL) &&
  2031.          (cfile[0])      &&
  2032.          (FindPort(port) != NULL) &&
  2033.          ((fullPath = FullPathOf(cfile)) != NULL))
  2034.     {
  2035.         char *cmd;
  2036.         char *curDirPath = FullPathOf("");
  2037.  
  2038.     cmd = ScanReplace("Load Nil: %n %c", fullPath, "nil:", curDirPath);
  2039.     if (cmd != NULL)
  2040.     {
  2041.         /* Note that we don't care if this fails for any reason, we  */
  2042.         /* just want to give them an opportunity to purge any errors */
  2043.         /* that have been stored                                     */
  2044.         PlaceRexxCommandDirect(NULL,port,cmd,NULL,NULL);
  2045.         free(cmd);
  2046.     }
  2047.     if (curDirPath != NULL) free(curDirPath);
  2048.     free(fullPath);
  2049.     }
  2050. }
  2051.  
  2052. /*
  2053.  *  HANDLEERRORREXX()
  2054.  *
  2055.  *  Scan DCC:CONFIG/DCC.CONFIG to obtain REXX command execution information
  2056.  *  then attempt to run the appropriate command.  If the REXX script returns
  2057.  *  2 we retry the compilation.  If the REXX script returns anything else
  2058.  *  we abort.
  2059.  *
  2060.  *  cfile can be "", indicating no source file available to handle error(s)
  2061.  */
  2062.  
  2063. int
  2064. HandleErrorRexx(cfile, cmdbuf, rc)
  2065. char *cfile;
  2066. char *cmdbuf;
  2067. int rc;
  2068. {
  2069.     FILE *fi;
  2070.     int r = -1;
  2071.     char *buf;
  2072.     char *fullPath;
  2073.     char *cmdName = "cmd=";
  2074.     char *portName = "port=";
  2075.     char *rexxCmdName = "rexxcmd=";
  2076.     char *curDirPath = FullPathOf("");
  2077.  
  2078.  
  2079.     if (buf = malloc(256)) {
  2080.     /*
  2081.      *  obtain full path to cFile, if present
  2082.      */
  2083.  
  2084.     if ((cfile != NULL) && cfile[0]) {
  2085.         fullPath = FullPathOf(cfile);
  2086.     } else {
  2087.         fullPath = strdup("");
  2088.         cmdName = "linkcmd=";
  2089.         portName = "linkport=";
  2090.         rexxCmdName = "linkrexxcmd=";
  2091.     }
  2092.     if (fullPath) {
  2093.         /*
  2094.          *    open the config file
  2095.          */
  2096.  
  2097.         if (fi = fopen("DCC:CONFIG/DCC.CONFIG", "r")) {
  2098.         char *cmd = NULL;
  2099.         char *port = NULL;
  2100.         char *rexxcmd = NULL;
  2101.  
  2102.         while (fgets(buf, 256, fi)) {
  2103.             if (strnicmp(buf, cmdName, strlen(cmdName)) == 0)
  2104.             cmd = ScanReplace(buf + strlen(cmdName), fullPath, ErrFile, curDirPath);
  2105.             else if (strnicmp(buf, portName, strlen(portName)) == 0)
  2106.             port = ScanReplace(buf + strlen(portName), fullPath, ErrFile, curDirPath);
  2107.             else if (strnicmp(buf, rexxCmdName, strlen(rexxCmdName)) == 0)
  2108.             rexxcmd= ScanReplace(buf + strlen(rexxCmdName), fullPath, ErrFile, curDirPath);
  2109.         }
  2110.         fclose(fi);
  2111.  
  2112.         if (Verbose) {
  2113.             printf("cmd=%s port=%s rexxcmd=%s file=%s\n",
  2114.             (cmd ? cmd : ""),
  2115.             (port ? port : ""),
  2116.             (rexxcmd ? rexxcmd : ""),
  2117.             fullPath
  2118.             );
  2119.         }
  2120.  
  2121.         Forbid();
  2122.         if (port && rexxcmd) {
  2123.             /*
  2124.             *  Attempt to run the CLI command that starts up the
  2125.             *  editor (or whatever)
  2126.             */
  2127.  
  2128.             {
  2129.             short retry = 0;
  2130.  
  2131.             while (FindPort(port) == NULL && retry < 5 && cmd) {
  2132.                 if (retry == 0)
  2133.                 Execute(cmd, NULL, NULL);
  2134.                 Delay(50);
  2135.                 ++retry;
  2136.             }
  2137.             }
  2138.  
  2139.             /*
  2140.             *  If port found place a REXX command directly to the port
  2141.             */
  2142.  
  2143.             if (FindPort(port)) {
  2144.             long ec;
  2145.  
  2146.             Permit();
  2147.             r = PlaceRexxCommandDirect(NULL,port,rexxcmd,NULL,&ec);
  2148.             Forbid();
  2149.             if (Verbose)
  2150.                 printf("R = %d %d\n", r, ec);
  2151.             ec = r;
  2152.             }
  2153.         } else if (cmd) {
  2154.             Execute(cmd, NULL, NULL);
  2155.         }
  2156.         Permit();
  2157.         if (cmd)
  2158.             free(cmd);
  2159.         if (port)
  2160.             free(port);
  2161.         if (rexxcmd)
  2162.             free(rexxcmd);
  2163.         } else {
  2164.         printf("can't open dcc:config/dcc.config\n");
  2165.         }
  2166.         free(fullPath);
  2167.     }
  2168.     free(buf);
  2169.     }
  2170.     return(r);
  2171. }
  2172.  
  2173. DoRexxCommand(msg, port, arg0, pres)
  2174. void *msg;
  2175. struct MsgPort *port;
  2176. char *arg0;
  2177. char **pres;
  2178. {
  2179.     return(20);
  2180. }
  2181.  
  2182. /*
  2183.  *  Handle %f/%e/%d/%n replacement in dcc.config
  2184.  */
  2185.  
  2186. char *
  2187. ScanReplace(buf, cFile, errFile, curDirPath)
  2188. char *buf;
  2189. char *cFile;
  2190. char *errFile;
  2191. char *curDirPath;
  2192. {
  2193.     char *s;
  2194.     char *rbuf;
  2195.     short i;
  2196.     short len;
  2197.     short dpindex;  /*    directory part index, char after directory  */
  2198.     short fpindex;  /*    file part index, char beginning file        */
  2199.  
  2200.     /*
  2201.      *    Split cFile into directory part and file part
  2202.      */
  2203.  
  2204.     for (dpindex = strlen(cFile) - 1; dpindex >= 0; --dpindex) {
  2205.     if ((cFile[dpindex] == ':') || (cFile[dpindex] == '/'))
  2206.         break;
  2207.     }
  2208.     ++dpindex;
  2209.     fpindex = dpindex;
  2210.  
  2211.     if (cFile[fpindex] == ':')
  2212.     ++fpindex;
  2213.  
  2214.     /*
  2215.      *    Actual scan
  2216.      */
  2217.  
  2218.     while (*buf == ' ' || *buf == '\t')
  2219.     ++buf;
  2220.     rbuf = NULL;
  2221.     for (i = 0; i < 2; ++i) {
  2222.     len = 0;
  2223.  
  2224.     for (s = buf; *s; ++s) {
  2225.         if (*s == '%') {
  2226.         ++s;
  2227.         switch(*s) {
  2228.         case 'f':       /*  %f - source file    */
  2229.             if (rbuf)
  2230.             sprintf(rbuf + len, "%s", cFile);
  2231.             len += strlen(cFile);
  2232.             continue;
  2233.         case 'e':       /*  %e - error file     */
  2234.             if (rbuf)
  2235.             sprintf(rbuf + len, "%s", errFile);
  2236.             len += strlen(errFile);
  2237.             continue;
  2238.         case 'd':
  2239.             if (rbuf)
  2240.             sprintf(rbuf + len, "%.*s", dpindex, cFile);
  2241.             len += dpindex;
  2242.             continue;
  2243.         case 'n':
  2244.             if (rbuf)
  2245.             sprintf(rbuf + len, "%s", cFile + fpindex);
  2246.             len += strlen(cFile + fpindex);
  2247.             continue;
  2248.         case 'c':
  2249.             if (rbuf)
  2250.             sprintf(rbuf + len, "%s", curDirPath);
  2251.             len += strlen(curDirPath);
  2252.             continue;
  2253.         case '0':
  2254.         case '1':
  2255.         case '2':
  2256.         case '3':
  2257.         case '4':
  2258.         case '5':
  2259.         case '6':
  2260.         case '7':
  2261.         case '8':
  2262.         case '9':
  2263.             {
  2264.             char *aptr = RexxReplace[*s - '0'];
  2265.  
  2266.             if (aptr == NULL)
  2267.                 aptr = "?";
  2268.             if (rbuf)
  2269.                 sprintf(rbuf + len, "%s", aptr);
  2270.             len += strlen(aptr);
  2271.             }
  2272.             continue;
  2273.         }
  2274.         --s;
  2275.         }
  2276.         if (*s == '\n')
  2277.         continue;
  2278.         if (rbuf)
  2279.         rbuf[len] = *s;
  2280.         ++len;
  2281.     }
  2282.     if (i == 0)
  2283.         rbuf = malloc(len + 1);
  2284.     }
  2285.     if (rbuf)
  2286.     rbuf[len] = 0;
  2287.     else
  2288.     rbuf = strdup("");
  2289.     return(rbuf);
  2290. }
  2291.  
  2292. char *
  2293. FullPathOf(file)
  2294. char *file;
  2295. {
  2296.     BPTR lock;
  2297.     BPTR dlock;
  2298.     __aligned FIB fib;
  2299.     char *s1 = strdup(file);
  2300.  
  2301.     if (lock = Lock(file, SHARED_LOCK))
  2302.     {
  2303.     if (Examine(lock, &fib))
  2304.     {
  2305.         short i = 0;
  2306.         free(s1);
  2307.         i = strlen(fib.fib_FileName);
  2308.         s1 = malloc(i + 2);
  2309.         strcpy(s1, fib.fib_FileName);
  2310.         s1[i+1] = '\0';  /* Ensure we have have a null terminator when we */
  2311.                          /* Insert the colon if this is the root only     */
  2312.         while (dlock = ParentDir(lock))
  2313.         {
  2314.         UnLock(lock);
  2315.         lock = dlock;
  2316.         if (Examine(lock, &fib))
  2317.         {
  2318.             char *s2;
  2319.             s2 = malloc(strlen(s1) + strlen(fib.fib_FileName) + 2);
  2320.             sprintf(s2, "%s/%s", fib.fib_FileName, s1);
  2321.             free(s1);
  2322.             s1 = s2;
  2323.             i = strlen(fib.fib_FileName);
  2324.         }
  2325.         }
  2326.         s1[i] = ':';
  2327.     }
  2328.     UnLock(lock);
  2329.     }
  2330.     return(s1);
  2331. }
  2332.  
  2333. #endif
  2334. #endif
  2335.  
  2336. /*
  2337.  *  Exit with a code, the -unixrc option causes unix style
  2338.  *  exit codes to be used (0 on no error or warning, 1 on error)
  2339.  */
  2340.  
  2341. void
  2342. uexit(int code)
  2343. {
  2344.     if (UnixRCOpt) {
  2345.     if (code <= 5)
  2346.         code = 0;
  2347.     else
  2348.         code = 1;
  2349.     }
  2350.     exit(code);
  2351. }
  2352.  
  2353.